package cn.wgx.study.juc;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.LockSupport;

public class ThreadLockSupport {

    static Thread t1, t2;

    /**
     * 两条字符串轮询输出
     *
     * @param args
     */
    public static void main(String[] args) {

        char[] cI = "1234567890".toCharArray();

        char[] cc = "ABCDEFGHIJ".toCharArray();

//        lockSupport(cI, cc);
        notifyWait(cI, cc);
//        selfAround(cI, cc);

    }


    /**
     * 方法一  lockSupport.unpark
     *
     * @param cI
     * @param cc
     */
    public static void lockSupport(char[] cI, char[] cc) {
        System.out.print("方法一: ");
        t1 = new Thread(() -> {
            for (char c : cI) {
                System.out.print(c);
                LockSupport.unpark(t2);
                LockSupport.park();
            }
            LockSupport.unpark(t2);
        });

        t2 = new Thread(() -> {
            for (char c : cc) {
                LockSupport.park();
                System.out.print(c);
                LockSupport.unpark(t1);
            }
        });

        t1.start();
        t2.start();
    }

    /**
     * 方法二  notify   Wait
     *
     * @param cI
     * @param cc
     */
    public static void notifyWait(char[] cI, char[] cc) {
        System.out.print("方法二: ");
        Object o = new Object();

        t1 = new Thread(() -> {

            synchronized (o) {
                for (char c : cI) {
                    System.out.print(c);
                    try {
                        o.notify();
                        o.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                o.notify();
            }
        });

        t2 = new Thread(() -> {
            synchronized (o) {
                for (char c : cc) {
                    try {
                        System.out.print(c);
                        o.notify();
                        o.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                o.notify();
            }
        });

        t1.start();
        t2.start();
    }

    enum Ready {t1, t2}

    static Ready r = Ready.t1;

    static AtomicInteger atomicInteger = new AtomicInteger(1);

    /**
     * 方法二  自旋 , 线程空转, CPU占用高
     *
     * @param cI
     * @param cc
     */
    public static void selfAround(char[] cI, char[] cc) {
        System.out.print("方法三: ");


        t1 = new Thread(() -> {
            for (char c : cI) {
                while (r != Ready.t1) {
                }
                System.out.print(c);
                r = Ready.t2;
            }
        });

        t2 = new Thread(() -> {
            for (char c : cc) {
                while (r != Ready.t2) {
                }
                System.out.print(c);
                r = Ready.t1;
            }
        });

        t1.start();
        t2.start();

        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
